//----------------------------------
//-----StuffLauncher SWEP-----------
//----------Made by Brian Nevec-----
//----------------------------------
//---Part of the SMOD Weapons Pack--
//----------------------------------

//if on server
if SERVER then

	//send this file
	AddCSLuaFile("shared.lua");

	//and set some hold type thingy
	SWEP.HoldType			= "rpg";

end

//if on client
if CLIENT then

	//set some information about it
	SWEP.PrintName			= "Stuff Launcher";
	SWEP.Author				= "Brian Nevec";
	SWEP.Slot				= 4;
	SWEP.SlotPos			= 3;
	SWEP.Purpose			= "Launches stuff";
	SWEP.Instructions		= "Right Click: Pick model, Left Click: Throw, Reload: Remove thrown objects";

	//set the category to SMOD
	SWEP.Category			= "SMOD";

	//selection icon
	SWEP.WepSelectIcon = surface.GetTextureID("weapons/stufficon");

	-- Kill Icon
	if(file.Exists("../materials/weapons/stuff_killicon.vmt")) then

		killicon.Add("weapon_stufflauncher","weapons/stuff_killicon",Color(255,255,255));

	end 

end

//is it spawnable? and is it admin only?
SWEP.Spawnable				= true;
SWEP.AdminSpawnable			= false;

//view/world models
SWEP.ViewModel				= "models/weapons/v_rpg.mdl";
SWEP.WorldModel				= "models/weapons/w_rocket_launcher.mdl";

//some more settings
SWEP.Weight					= 25;
SWEP.AutoSwitchTo			= false;
SWEP.AutoSwitchFrom			= false;

//primary ammo
SWEP.Primary =
{
	ClipSize				= -1,
	DefaultClip				= -1,
	Automatic				= true,
	Ammo					= "none"
}

//secondary ammo
SWEP.Secondary =
{
	ClipSize				= -1,
	DefaultClip				= -1,
	Automatic				= true,
	Ammo					= "none"
}

//sounds
SWEP.Sounds =
{
	Launch = Sound("weapons/crossbow/fire1.wav"),
	Fail = Sound("weapons/physcannon/physcannon_drop.wav"),
	Absorb = Sound("weapons/physcannon/physcannon_pickup.wav"),
	Remove = Sound("weapons/stunstick/stunstick_impact1.wav")
}

//current model
SWEP.FireModel = "models/props_junk/watermelon01.mdl";

//current skin
SWEP.ModelSkin = 0;

//do we have an npc?
SWEP.HasNpc = false;
SWEP.NPCClass = "";

//when the swep initializes
function SWEP:Initialize()

	//if on server
	if SERVER then

		//set the hold type
		self:SetWeaponHoldType(self.HoldType);

	end

end

//primary attack
function SWEP:PrimaryAttack()

	//if on server
	if SERVER then

		//default the thrown props table
		self.Owner.ThrownProps = self.Owner.ThrownProps or {};

		//pos, ang
		local Pos = self.Owner:GetShootPos();
		local Ang = self.Owner:EyeAngles();

		//adjust the pos so it looks like the props are going out of the gun instead of your face
		Pos = Pos + Ang:Forward() * 15 + Ang:Right() * 15 + Ang:Up() * -5;

		Ang = (self.Owner:GetEyeTraceNoCursor().HitPos - Pos):Angle();

		//prop entity
		local Prop = nil;

		//if we have an npc stored
		if self.HasNPC then

			//create it
			Prop = ents.Create(self.NPCClass);

			//change the pos and ang to something that the npc likes
			Pos = self.Owner:GetEyeTraceNoCursor().HitPos;
			Ang = Angle(0,self.Owner:GetAngles().y,0);

			//make it friendly
			Prop:AddEntityRelationship(self.Owner,D_LI,50);

		else

			//if not, spawn a normal prop
			Prop = ents.Create("prop_physics");

		end

		//if it is valid
		if ValidEntity(Prop) then

			//set the info
			Prop:SetPos(Pos);
			Prop:SetAngles(Ang);
			Prop:SetModel(self.FireModel);
			Prop:SetPhysicsAttacker(self.Owner);
			Prop:Spawn();
			Prop:SetSkin(self.ModelSkin);

			//if we don't have an npc
			if !self.HasNPC then

				//get its physics object
				local Physics = Prop:GetPhysicsObject();

				//if it is valid
				if ValidEntity(Physics) then

					//throw it
					Physics:ApplyForceCenter(Physics:GetMass() * self.Owner:GetAimVector() * math.Rand(1500,2000) * 0.5);

					//also set the owner(for nocollide)
					Prop:SetOwner(self.Owner);

					//and after .5 seconds remove the owner
					timer.Simple(0.5,
					function()

						if ValidEntity(Prop) then

							Prop:SetOwner();

						end

					end)

				else

					//else, remove it
					Prop:Remove();

				end

			end

			//if the prop is still valid
			if ValidEntity(Prop) then

				//play sound
				self.Owner:EmitSound(self.Sounds.Launch);

				//and play animations
				self.Weapon:SendWeaponAnim(ACT_VM_PRIMARYATTACK);
				self.Owner:SetAnimation(PLAYER_ATTACK1);

				//add it to the previously mentioned table
				table.insert(self.Owner.ThrownProps,Prop);

			end

		end

	end

	//set primary fire delay
	self:SetNextPrimaryFire(CurTime() + 0.32);

	//we don't want to play any of the default stuff
	return false;

end

//secondary fire
function SWEP:SecondaryAttack()

	//if on server
	if SERVER then

		//get the entity the owner is looking at
		local Ent = self.Owner:GetEyeTraceNoCursor().Entity;

		//did we get it?
		local Success = false;

		//if it's valid, is not world, is not player
		if ValidEntity(Ent) && !Ent:IsWorld() && !Ent:IsPlayer() then

			//if it has a valid model
			if Ent:GetModel() && Ent:GetModel() != "" then

				//if it's different than the current model
				if Ent:GetModel() != self.FireModel then

					//emit a sound
					self.Owner:EmitSound(self.Sounds.Absorb);

					//save the model
					self.FireModel = Ent:GetModel();

					//and save the skin
					self.ModelSkin = Ent:GetSkin();

					//if it is an npc
					if Ent:IsNPC() then

						//i don't want to mess around with the barnacle
						if Ent:GetClass() != "npc_barnacle" then

							//tell everyone that we have an npc
							self.HasNPC = true;
							self.NPCClass = Ent:GetClass();

						else

							//if it was that wall sucker thing then get out
							self:SetNextSecondaryFire(CurTime() + 0.5);

							return false;

						end

					else

						//else, tell that we have a normal prop
						self.HasNPC = false;

					end

					//create our dissolver
					local D = ents.Create("env_entity_dissolver");
					D:SetKeyValue("dissolvetype",4);
					D:SetKeyValue("magnitude",0);
					D:SetPhysicsAttacker(self.Owner);
					D:SetPos(Vector(0,0,0));
					D:Spawn();

					//set our targets name
					Ent:SetName("StuffLauncher_TARGET_LOL");

					//and dissolve it
					D:Fire("Dissolve",Ent:GetName());
					D:Fire("Kill","",0.1);

					//say that we succeeded
					Success = true;

				end

			end

		end

		//if we didn't
		if !Success then

			//play a fail sound
			self.Owner:EmitSound(self.Sounds.Fail);

		end

	end

	//and secondary day
	self:SetNextSecondaryFire(CurTime() + 0.5);

	return false;

end

//reload
function SWEP:Reload()

	//if server
	if SERVER then

		self.Owner.ThrownProps = self.Owner.ThrownProps or {};

		//for each thrown prop
		for Index,Prop in pairs(self.Owner.ThrownProps) do

			//if it's valid
			if ValidEntity(Prop) then

				//after some random time(to make it look/sound cooler
				timer.Simple(Index * 0.3 + math.Rand(0.3,0.5),
				function()

					//if it's still valid, and our owner is valid
					if ValidEntity(Prop) && ValidEntity(self.Owner) then

						//play sound
						Prop:EmitSound(self.Sounds.Remove);

						//again with the dissolver
						local D = ents.Create("env_entity_dissolver");
						D:SetKeyValue("dissolvetype",4);
						D:SetKeyValue("magnitude",0);
						D:SetPhysicsAttacker(self.Owner);
						D:SetPos(Vector(0,0,0));
						D:Spawn();

						//set name
						Prop:SetName("StuffLauncher_TARGET_LOL_FOR_REMOVAL");

						//and dissolve it
						D:Fire("Dissolve",Prop:GetName());
						D:Fire("Kill","",0.1);

					end

				end)

			end

			//and remove it from the table
			table.remove(self.Owner.ThrownProps,Index);
			
		end

	end

end

//when we deploy
function SWEP:Deploy()

	//run the deploy animation
	self.Weapon:SendWeaponAnim(ACT_VM_DRAW);

	//and return
	return true;

end